package com.zhouheng.common.config;

import com.zhouheng.common.jwtfilter.JWTAuthenticationFilter;
import com.zhouheng.common.jwtfilter.JWTLoginFilter;
import com.zhouheng.common.security.CustomAuthenticationProvider;
import com.zhouheng.module.dao.SysUserMapper;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;

/**
 * SpringSecurity配置类
 * <p>
 * 通过SpringSecurity的配置，将JWTLoginFilter，JWTAuthenticationFilter组合在一起
 * <p>
 * securedEnabled = true 注解控制方法权限
 * prePostEnabled = true
 * jsr250Enabled = true
 *
 * @author 周恒
 * @date 20180831 15:19:23
 * @since v1.0
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * userDetailsService security的用户详细信息服务，身份认证时需要使用，注入我们实现了这个接口的类
     */
    private UserDetailsService userDetailsService;

    /**
     * sysUserMapper 系统用户dao
     */
    private SysUserMapper sysUserMapper;

    public WebSecurityConfig(UserDetailsService userDetailsService, SysUserMapper sysUserMapper) {
        this.userDetailsService = userDetailsService;
        this.sysUserMapper = sysUserMapper;
    }

    /**
     * 设置HTTP验证规则
     *
     * @param http 描述此参数
     * @author 周恒
     * @date 20200120 16:41:45
     * @since v1.0
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                //会话创建策略：无状态
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                //排除注册请求和获取验证码请求（登录接口不需要排除）
                .antMatchers(HttpMethod.POST, "/user/signUp").permitAll()
                .antMatchers(HttpMethod.GET, "/user/captcha").permitAll()
                //其余所有请求需要身份认证
                .anyRequest().authenticated()
                .and()
                //添加拦截器
                .addFilter(new JWTLoginFilter(authenticationManager()))
                .addFilter(new JWTAuthenticationFilter(authenticationManager()));
    }

    /**
     * 使用自定义身份验证组件
     *
     * @param auth 身份认证管理器
     * @author 周恒
     * @date 20200120 16:41:45
     * @since v1.0
     */
    @Override
    public void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(new CustomAuthenticationProvider(userDetailsService, sysUserMapper));
    }

}
